import { defineStore } from "pinia";
import { sessionStorage } from "mp-storage";
import { funDelay } from "@/utils/tools/function";

export default defineStore("SocketStore", {
  //*全局仓库
  state: initState,
  //*全局函数
  actions: {
    connectSocket(count = 1) {
      return new Promise<void>((resolve, reject) => {
        if (count >= 3) return reject();
        this.connecting = true;
        uni.connectSocket({
          url: import.meta.env.VITE_SOCKET_URL,
          method: "GET",
          header: {
            "content-type": "application/json",
          },
          success: () => {
            this.connecting = false;
            resolve();
            console.error("调起webSocket成功");
            uni.onSocketError((error) => {
              this.socketConnected = false;
              console.error("socket error:", error);
              this.connectSocket();
            });
            uni.onSocketClose(() => {
              console.log("socket close");
              this.socketConnected = false;
            });
            uni.onSocketOpen(() => {
              console.log("socket open");
              this.socketConnected = true;
            });
            uni.onSocketMessage((res) => {
              console.log("socket message", res);
            });
          },
          fail: (error) => {
            this.connecting = false;
            console.error(`调起webSocket失败第${count}次：`, error);
            funDelay(this.connectSocket, [++count], 3000);
          },
        });
      });
    },
    /**通过 WebSocket 连接发送数据 */
    sendSocketMessage(
      data: SendSocketReq,
      config?: Partial<UniNamespace.SendSocketMessageOptions>
    ) {
      try {
        console.log("sendSocketMessage", data);

        uni.sendSocketMessage({
          ...config,
          data: JSON.stringify(data),
        });
      } catch (error) {
        console.error(error);
      }
    },
    /**监听WebSocket接受到服务器的消息事件 */
    onSocketMessage(fun: (d: GetSocketRes) => void) {
      uni.onSocketMessage((e) => fun(JSON.parse(e.data || "{}")));
    },
  },
  //*计算属性
  getters: {},
  //*仓库数据缓存
  persist: [
    // {
    //   key: "SocketStore",
    //   storage: sessionStorage, //指定储存位置
    // },
  ],
});
/**state类型定义 */
interface SocketStore {
  socketConnected: boolean;
  connecting: boolean;
}
/**初始化pinia */
function initState(): SocketStore {
  return {
    socketConnected: false,
    connecting: false,
  };
}

export type SendSocketReq = CheckToken.Req | Ping.Req;
export type GetSocketRes = ChatData.Res;

/**身份认证 */
export namespace CheckToken {
  export type Req = SocketReq.ReqModule<"checkToken", string>;
}
/**webSocket心跳 */
export namespace Ping {
  export interface Req {
    action: "ping";
  }
}
/**评论推送 */
export namespace ChatData {
  export type Res = SocketRes.ResModule<"chatData", ChatData.Data>;
  export interface Msg {
    content: string;
    id: string;
    time: number;
    type: string;
    user_info: User_info;
  }
  export interface User_info {
    face: string;
    name: string;
    uid: number;
  }
  export interface Data {
    list_id: string;
    data: Data2;
  }
  export interface Data2 {
    type: number;
    msg: Msg;
  }
}

export namespace SocketReq {
  export type ActionReq = "checkToken" | "ping";
  export interface ReqModule<K extends ActionReq, D> {
    action: K;
    data: D;
  }
}
export namespace SocketRes {
  export interface ResModule<K extends ActionRes, D> {
    action: K;
    data: D;
  }

  export type ActionRes = "chatData";
}
